<script setup lang="ts">
  import GenTable, { AiGenTable, AiGenTableColumn, CreateGenTableByAi, GenAiForm, GeneratorApi, GenTableField } from '@/views/gen/table/model'
  import { camelCase, upperFirst } from 'lodash-es'
  import { FormInst, UploadFileInfo } from 'naive-ui'
  import { commonFields } from '@/views/gen/table/commonFields'
  import { OllamaChatModel } from '@/api/aiChat'

  const showModal = ref<boolean>(false)
  const formData = ref<GenAiForm>({
    checkedCommFields: commonFields.map(({ columnName }) => columnName!)
  })
  const genTable = ref<GenTable>()
  const formRef = ref<FormInst>()
  const loading = ref<boolean>(false)
  const dbTableName = ref<string>('')
  const uiImages = ref<string[]>([])

  const aiGenTable = ref<AiGenTable>()

  const show = (tableName?: string) => {
    console.log('show')
    showModal.value = true
    formData.value.tableName = tableName
  }

  const emits = defineEmits<{
    (e: 'complete', data: GenTable): void
  }>()

  const defTable: GenTable = {
    tableType: 'single',
    dataSource: 'master',
    // izSync: 1,
    izSimpleQuery: 1,
    izPage: 1,
    izTree: 0,
    formType: 0
  }

  const handleOk = async () => {
    if (loading.value) {
      return
    }
    if (!genTable.value) {
      window.$message.warning('请先填写表结构')
      return
    }
    loading.value = true
    const { tableFields = [], ...table } = genTable.value
    const { checkedCommFields = [], checkedAiFields = [] } = formData.value
    const allFields: GenTable['tableFields'] = [...tableFields, ...commonFields]
    emits('complete', {
      ...table,
      tableFields: allFields.filter(({ columnName }) => columnName && [...checkedCommFields, ...checkedAiFields]?.includes(columnName))
    })
    loading.value = false
    // close()
    return false
  }

  const close = () => {
    // formRef.value?.close()
    showModal.value = true
  }

  const handleUploadChange = (options: { file: UploadFileInfo; fileList: Array<UploadFileInfo>; event?: Event }) => {
    const fileTiBase64 = (file?: File | null): Promise<string> => {
      if (!file) return Promise.resolve('')
      return new Promise((resolve) => {
        const reader = new FileReader()
        reader.onload = (e) => {
          const base64String = e.target?.result as string
          // 去除base64前缀
          const base64StringWithoutPrefix = base64String.substring(base64String.indexOf(',') + 1)
          resolve(base64StringWithoutPrefix)
        }
        reader.readAsDataURL(file)
      })
    }

    Promise.all(
      options.fileList.map(async ({ file }) => {
        return await fileTiBase64(file)
      })
    ).then((res) => {
      uiImages.value = res
    })
  }

  const columnTransform = (column: AiGenTableColumn): GenTableField => {
    const {
      columnComment: description,
      shortColumnComment: showName,
      columnLength: length,
      columnPrecision: decimalPlaces,
      columnName,
      formType,
      jdbcType,
      javaType,
      showAdd,
      showTable,
      showEdit,
      showSearch,
      disableOnAdd,
      disableOnEdit,
      required,
      allowNull,
      ...item
    } = column

    const formattedJavaType = upperFirst(camelCase(javaType))
    const formattedFieldName = camelCase(columnName)

    const booleanToNumber = (value: boolean | undefined) => (value ? 1 : 0)

    return {
      ...item,
      columnName,
      length,
      decimalPlaces,
      showAdd: booleanToNumber(showAdd),
      showEdit: booleanToNumber(showEdit),
      showTable: booleanToNumber(showTable),
      showSearch: booleanToNumber(showSearch),
      disableOnAdd: booleanToNumber(disableOnAdd),
      disableOnEdit: booleanToNumber(disableOnEdit),
      required: booleanToNumber(required),
      allowNull: booleanToNumber(allowNull),
      description: showName ?? description,
      jdbcType: jdbcType.toLowerCase(),
      formType: formType.toLowerCase(),
      javaType: formattedJavaType,
      fieldName: formattedFieldName
    }
  }

  const createByAi = async () => {
    loading.value = true
    const { tableName = '' } = formData.value
    const params: CreateGenTableByAi = {
      description: tableName,
      images: uiImages.value,
      model: selectedModel.value
    }
    const resp = await GeneratorApi.createGenTableByAi(params)
      .catch((err) => {
        window.$message.error(err?.message ?? '生成失败')
      })
      .finally(() => {
        loading.value = false
      })
    console.log('resp: ', resp)
    aiGenTable.value = resp?.data
    if (resp?.data) {
      const { tableName: name, tableSummary: summary, tableComment: description, columns } = resp?.data
      formData.value.checkedAiFields = columns?.filter(({ columnName }) => columnName).map(({ columnName }) => columnName!) || []
      const aiColumns: GenTableField[] = columns.map(columnTransform)
      genTable.value = { name, summary, description, tableFields: aiColumns }
      dbTableName.value = name ?? ''
      genTable.value = { ...defTable, ...genTable.value } as GenTable
    }
  }

  const aiModels = ref<OllamaChatModel[]>()
  const selectedModel = ref<string>(aiModels[0])

  defineExpose<{
    show: (tableName?: string) => void
    close: () => void
  }>({
    show,
    close
  })
</script>

<template>
  <n-drawer v-model:show="showModal" width="50%">
    <n-drawer-content>
      <template #header>
        <n-space> Ai 生成表结构</n-space>
      </template>
      <n-form ref="formRef" :model="formData" label-placement="left" label-width="100">
        <n-form-item label="表描述" path="tableName" span="22">
          <n-input v-model:value="formData.tableName" type="textarea" style="white-space: pre-wrap; width: 100%" rows="5" @keyup.ctrl.enter="createByAi">
            <template #suffix>
              <n-button circle quaternary type="success" class="ai-action-btn" :loading="loading" @click="createByAi">
                <template #icon>
                  <Icon icon-name="InfiniteOutline" />
                </template>
              </n-button>
            </template>
          </n-input>
        </n-form-item>
        <n-form-item label="设计图" span="9" offset="1">
          <n-upload list-type="image-card" @change="handleUploadChange" />
        </n-form-item>
        <n-form-item v-if="dbTableName" label="表名" span="22" offset="1">
          <n-input :value="dbTableName" readonly />
        </n-form-item>
        <n-grid>
          <n-form-item-gi label="通用字段" span="22" path="checkedFields">
            <n-checkbox-group v-model:value="formData.checkedCommFields">
              <n-checkbox v-for="field in commonFields" :key="field.columnName" :label="field.description" :value="field.columnName" />
            </n-checkbox-group>
          </n-form-item-gi>
          <n-form-item-gi v-if="genTable?.tableFields" label="业务字段" span="22" path="checkedFields">
            <n-checkbox-group v-model:value="formData.checkedAiFields">
              <n-checkbox v-for="field in genTable?.tableFields" :key="field.columnName" :label="field.description" :value="field.columnName" />
            </n-checkbox-group>
          </n-form-item-gi>
        </n-grid>
      </n-form>
      <template #footer>
        <n-button secondary type="success" class="ai-action-btn" :loading="loading" @click="handleOk"> 确认</n-button>
      </template>
    </n-drawer-content>
  </n-drawer>
</template>

<style scoped></style>
